/*
 * Copyright (c) 2024 endless-sky
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef BASE_IPC_H
#define BASE_IPC_H

#include <string>
#include <vector>
#include <functional>
#include <memory>
#include <atomic>
#include <thread>

namespace El {
namespace Utils {

// 消息类，用于封装传输的字符串消息
class Message {
public:
    Message() = default;
    explicit Message(const std::string &data) : data_(data) {}

    const std::string &getData() const
    {
        return data_;
    }
    void setData(const std::string &data)
    {
        data_ = data;
    }

private:
    std::string data_;
};

// 服务端接口类，负责接收客户端的消息
class Server {
public:
    using MessageHandler = std::function<void(const Message &, Message &)>;

    Server(const std::string &name);
    ~Server();

    // 启动服务器
    bool start();

    // 停止服务器
    void stop();

    // 设置消息处理回调
    void setMessageHandler(const MessageHandler &handler)
    {
        messageHandler_ = handler;
    }

    // 服务器是否正在运行
    bool isRunning() const
    {
        return running_;
    }

private:
    void serverLoop();

    std::string pipeName_;
    MessageHandler messageHandler_;
    std::atomic<bool> running_{false};
    std::unique_ptr<std::thread> serverThread_;

    // 平台特定的文件描述符
    int pipeHandle_ = -1;
};

// 客户端接口类，负责向服务端发送消息
class Client {
public:
    Client(const std::string &serverName);
    ~Client();

    // 连接到服务器
    bool connect();

    // 断开连接
    void disconnect();

    // 发送消息并接收回复
    bool sendMessage(const Message &request, Message &response);

    // 是否已连接
    bool isConnected() const
    {
        return connected_;
    }

private:
    std::string serverName_;
    bool connected_ = false;

    // 平台特定的文件描述符
    int pipeHandle_ = -1;
};

} // namespace Utils
} // namespace El

#endif // BASE_IPC_H
